package org.cyhz.standardize.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import jxl.Sheet;
import jxl.Workbook;

import org.apache.commons.lang.StringUtils;
import org.cyhz.domain.SbNbVO;
import org.cyhz.domain.SbSsVO;
import org.cyhz.domain.SbVO;
import org.cyhz.domain.SsNsVO;
import org.cyhz.domain.SsVO;
import org.cyhz.util.ExcelUtil;
import org.cyhz.util.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * <pre>
 * S(uppercase):Standard (标准)
 * N(uppercase):Nonstandard (非标准)
 * s(lowercase):series (车系)
 * b(lowercase):brand (品牌)
 * Sb:standard brand (标准品牌)
 * Ns:nonstandard series (非标准车系)
 * </pre>
 * 
 * @Title: StandardizeResources.java
 * @Package org.cyhz.standardize.service
 * @Description: 标准化用到的资源，主要用于节省查询时间而使用的不同的数据结构存储各实体之间的关联
 * @author Corleone
 * @date 2013年11月20日 下午1:15:24
 * @version V1.0
 */
@Component
public class StandardizeResources {

	@Value("#{configSettings['series.other']}")
	public static String otherSeries;

	@Value("#{configSettings['brand.other']}")
	public static String otherBrand;

	private static String configfile;

	private static String basePath = StandardizeResources.class
			.getResource("/").getPath();

	@Autowired(required = true)
	public void setConfigfile(
			@Value("#{configSettings['brand_series_config_file']}") String configfile) {
		StandardizeResources.configfile = configfile;
	}

	// 所有的标准品牌集合
	public static final List<SbVO> sbList = new ArrayList<>();

	// 所有的标准品牌集合
	public static final List<SsVO> ssList = new ArrayList<>();

	// 所有的标准品牌和标准车系关联对象
	public static final List<SbSsVO> sbssList = new ArrayList<>();

	// 标准品牌名称与标准品牌对象的关联
	public static final Map<String, SbVO> sbName_sbvoMapping = new HashMap<>();

	// 标准车系名称与标准车系对象的关联
	public static final Map<String, SsVO> ssName_ssvoMapping = new HashMap<>();

	// 标准品牌与非标准品牌之间的关联
	public static final Map<SbVO, List<String>> sbnbMapping = new HashMap<>();

	// 非标准品牌与对应的标准品牌的关联
	public static final Map<String, List<SbVO>> nbsbMapping = new HashMap<>();

	// 标准车系与非标准车系之间的关联
	public static final Map<SsVO, List<String>> ssnsMapping = new HashMap<>();

	// 非标准车系与对应的标准车系的关联
	public static final Map<String, List<SsVO>> nsssMapping = new HashMap<>();

	// 标准品牌和标准车系之间的关联
	public static final Map<SbVO, List<SsVO>> sbssMapping = new HashMap<>();

	// 标准车系与所属标准品牌之间的关联
	public static final Map<SsVO, List<SbVO>> sssbMapping = new HashMap<>();

	// 非标准品牌与标准非标品牌映射之间的关联
	public static final Map<String, List<SbNbVO>> nb_sbnbMapping = new HashMap<>();

	// 非标准车系与标准非标车系映射之间的关联
	public static final Map<String, List<SsNsVO>> ns_ssnsMapping = new HashMap<>();

	// 标准品牌&标准车系字符串
	public static final Set<String> sbssnameConcatString = new HashSet<>();

	public static final void buildSbSsName_SbSsMapping() {
		Log.info("按照sbssMapping，填充sbssname_sbssMapping");
		for (Entry<SbVO, List<SsVO>> sbss : sbssMapping.entrySet()) {
			if (null == sbss.getKey()) {
				Log.info("sbvo is null ? ");
			} else {
				for (SsVO ssvo : sbss.getValue()) {
					String sb = sbss.getKey().getSbrand();
					String ss = null;
					try {
						ss = ssvo.getSeries();
						sbssnameConcatString.add(sb + ss);
					} catch (Exception e) {
						// 某些品牌下的确没车系
					}
				}
			}
		}
	}

	private static final void buildNb_SbNbMapping() {
		Log.info("按照sbnbMapping，填充Nb_SbNbMapping");
		// 按照sbnbMapping，填充Nb_SbNbMapping
		if (sbnbMapping != null && sbnbMapping.size() > 0) {
			Set<SbVO> keys = sbnbMapping.keySet();
			for (SbVO key : keys) {
				List<String> values = sbnbMapping.get(key);
				for (String s : values) {
					SbNbVO sbnb = new SbNbVO();
					sbnb.setS(key.getSbrand());
					sbnb.setN(s);
					if (nb_sbnbMapping.containsKey(s)) {
						List<SbNbVO> slist = nb_sbnbMapping.get(s);
						if (!slist.contains(sbnb)) {
							slist.add(sbnb);
						}
						nb_sbnbMapping.put(s, slist);
					} else {
						List<SbNbVO> slist = new ArrayList<SbNbVO>();
						slist.add(sbnb);
						nb_sbnbMapping.put(s, slist);
					}
				}
			}
		}
	}

	private static final void buildNs_SsNsMapping() {
		Log.info("按照ssnsMapping，填充Ns_SsNsMapping");
		// 按照ssnsMapping，填充Ns_SsNsMapping
		if (ssnsMapping != null && ssnsMapping.size() > 0) {
			Set<SsVO> keys = ssnsMapping.keySet();
			for (SsVO key : keys) {
				List<String> values = ssnsMapping.get(key);
				for (String s : values) {
					SsNsVO ssns = new SsNsVO();
					ssns.setS(key.getSeries());
					ssns.setN(s);
					if (ns_ssnsMapping.containsKey(ssns)) {
						List<SsNsVO> slist = ns_ssnsMapping.get(ssns);
						if (!slist.contains(ssns)) {
							slist.add(ssns);
						}
						ns_ssnsMapping.put(s, slist);
					} else {
						List<SsNsVO> slist = new ArrayList<SsNsVO>();
						slist.add(ssns);
						ns_ssnsMapping.put(s, slist);
					}
				}
			}
		}
	}

	private static final void buildSbName_SbvoMapping() {
		Log.info("按照sbList，填充sbName_sbvoMapping");
		// 按照sbList，填充sbName_sbvoMapping
		for (SbVO sb : sbList) {
			sbName_sbvoMapping.put(sb.getSbrand(), sb);
		}
	}

	private static final void buildSsName_SsvoMapping() {
		Log.info("按照ssList，填充ssName_ssvoMapping");
		// 按照ssList，填充ssName_ssvoMapping
		for (SsVO ss : ssList) {
			ssName_ssvoMapping.put(ss.getSeries(), ss);
		}
	}

	private static final void readAndBuildSbList() {
		Log.info("填充标准品牌信息至sbList");
		// 读配置文件，填充标准品牌信息至sbList
		// 若sb重复，Log.warm出该sb
		Sheet sbsheet = getWorkBookOfSheet("Sb");
		List<Map<Integer, String>> list = ExcelUtil.readExcelForList(sbsheet);
		// 优化
		Map<String, String> existMap = new HashMap<>();
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Map<Integer, String> value = list.get(i);
				String sbrand = value.get(0).toUpperCase().trim();

				if (StringUtils.isBlank(sbrand)) {
					// ignore blank row
					continue;
				}
				SbVO sb = new SbVO(0, sbrand);
				if (existMap.containsKey(sbrand)) {
					Log.warn("sbList 中-" + sbrand + "-重复出现");
				} else {
					existMap.put(sbrand, sbrand);
					sbList.add(sb);
				}
			}
		}
	}

	private static final void readAndBuildSbSsList() {
		Log.info("填充标准品牌车系关联信息至sbssList");
		Sheet sbsheet = getWorkBookOfSheet("SbSs");
		List<Map<Integer, String>> list = ExcelUtil.readExcelForList(sbsheet);
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Map<Integer, String> value = list.get(i);
				String sbrand = value.get(0).trim().toUpperCase();
				String series = value.get(1).trim().toUpperCase();

				if (StringUtils.isBlank(sbrand) || StringUtils.isBlank(series)) {
					// ignore blank row
					continue;
				}
				if (StringUtils.isBlank(sbrand) || StringUtils.isBlank(series)) {
					Log.warn("标准品牌标准车系对应表SbSs 行 " + (1 + i) + " 标准品牌 或标准车系是空白 "
							+ sbrand + "ss:" + series);
					continue;
				}
				SbVO sb = null;
				if (sbName_sbvoMapping.containsKey(sbrand)) {
					sb = sbName_sbvoMapping.get(sbrand);
				} else {
					Log.warn("标准品牌标准车系对应表SbSs 行  " + (1 + i) + " 标准品牌  "
							+ sbrand + " 没有出现在标准品牌表中 Sb");
					continue;
				}
				SsVO ss = null;
				if (ssName_ssvoMapping.containsKey(series)) {
					ss = ssName_ssvoMapping.get(series);
				} else {
					Log.warn("标准品牌标准车系对应表SbSs 行  " + (1 + i) + " 标准车系 "
							+ series + " 没有出现在标准车系表中 Ss");
				}
				sbssList.add(new SbSsVO(sb, ss));
			}
		}
	}

	private static final void checkAllSsInSbSs() {
		Log.info("检查标准车系是否都在标准品牌标准车系中出现");
		for (SsVO ss : ssList) {
			if (!sssbMapping.containsKey(ss)) {
				Log.warn("标准车系 " + ss.getSeries() + " 没有对应的标准品牌");
			}
		}
	}

	private static final void checkAllSbInSbSs() {
		Log.info("检查标准品牌是否都在标准品牌标准车系中出现");
		for (SbVO sb : sbList) {
			if (!sbssMapping.containsKey(sb)) {
				Log.warn("标准品牌 " + sb.getSbrand() + " 下没有任何车系 ");
			}
		}
	}

	private static final void readAndBuildSsList() {
		Log.info("填充标准车系信息至ssList");
		// 读配置文件，填充标准车系信息至ssList
		// 若ss重复，Log.warm出该ss
		Map<String, String> exists = new HashMap<>();
		Sheet sbsheet = getWorkBookOfSheet("Ss");
		List<Map<Integer, String>> list = ExcelUtil.readExcelForList(sbsheet);
		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Map<Integer, String> value = list.get(i);
				String series = value.get(0).toUpperCase().trim();
				if (StringUtils.isBlank(series)) {
					// ignore blank row
					continue;
				}
				SsVO ss = new SsVO(0, series);
				if (exists.containsKey(series)) {
					Log.warn("标准车系 中-" + series + "-重复出现");
				} else {
					exists.put(series, series);
					ssList.add(ss);
				}
			}
		}
	}

	/**
	 * 追加标准品牌至标准品牌非标准品牌关联中
	 */
	private static final void appendSbToSbNbMapping() {
		for (Iterator<SbVO> sbi = sbList.iterator(); sbi.hasNext();) {
			SbVO sb = (SbVO) sbi.next();

			if (sbnbMapping.containsKey(sb)) {
				sbnbMapping.get(sb).add(sb.getSbrand());
			} else {
				List<String> nbs = new ArrayList<>();
				nbs.add(sb.getSbrand());
				sbnbMapping.put(sb, nbs);
			}
		}
	}

	private static final void readAndBuildSbNbMapping() {
		Log.info("读配置文件，填充sbnbMapping");
		// 读配置文件,填充sbnbMapping；
		// 若sb不在sbSet中出现，则Log.warm出该sb
		Sheet sbsheet = getWorkBookOfSheet("SbNb");
		List<Map<Integer, String>> list = ExcelUtil.readExcelForList(sbsheet);

		Map<String, String> exists = new HashMap<>();

		if (list != null && list.size() > 0) {
			for (int i = 0; i < list.size(); i++) {
				Map<Integer, String> value = list.get(i);
				String sbrand = value.get(0).trim().toUpperCase();
				String nbrand = value.get(1).trim().toUpperCase();

				if (StringUtils.isBlank(nbrand) && StringUtils.isBlank(sbrand)) {
					// ignore blank row
					continue;
				}

				if (StringUtils.isBlank(nbrand)) {
					Log.warn("标准品牌非标准品牌中，行 " + (1 + i) + " 非标准品牌为空");
					continue;
				}

				if (!sbName_sbvoMapping.containsKey(sbrand)) {
					Log.warn("标准品牌非标准品牌修订表中，行 " + (1 + i) + " 标准品牌 " + sbrand
							+ "有非标准品牌，但没出现标准品牌Sb中");
					continue;
				}

				String concat = sbrand + "-.-" + nbrand;

				if (exists.containsKey(concat)) {
					Log.info("标准品牌非标准品牌修订表中，行 " + (1 + i) + " 重复的品牌修订  "
							+ concat);
					continue;
				}

				SbVO vo = sbName_sbvoMapping.get(sbrand);
				vo.setSbrand(sbrand);
				if (sbnbMapping.containsKey(vo)) {
					if (!sbnbMapping.get(vo).contains(nbrand)) {
						sbnbMapping.get(vo).add(nbrand);
					}
				} else {
					List<String> sbStringList = new ArrayList<String>();
					sbStringList.add(nbrand);
					sbnbMapping.put(vo, sbStringList);
				}

				exists.put(concat, sbrand);
			}
		}

	}

	private static final void appendSsToSsNsMapping() {
		for (Iterator<SsVO> ssi = ssList.iterator(); ssi.hasNext();) {
			SsVO ss = (SsVO) ssi.next();

			if (ssnsMapping.containsKey(ss)) {
				ssnsMapping.get(ss).add(ss.getSeries());
			} else {
				List<String> nss = new ArrayList<>();
				nss.add(ss.getSeries());
				ssnsMapping.put(ss, nss);
			}
		}
	}

	private static final void readAndBuildSsNsMapping() {
		Log.info("读配置文件，填充ssnsMapping");
		// 读配置文件，填充ssnsMapping
		// 若ss不在ssSet中出现，则Log.warm出该ss
		Sheet sbsheet = getWorkBookOfSheet("SsNs");
		List<Map<Integer, String>> list = ExcelUtil.readExcelForList(sbsheet);

		Map<String, String> exists = new HashMap<>();

		if (list != null && list.size() > 0) {

			for (int i = 0; i < list.size(); i++) {
				Map<Integer, String> value = list.get(i);
				String series = value.get(0).trim().toUpperCase();
				String nseries = value.get(1).trim().toUpperCase();

				if (StringUtils.isBlank(series) && StringUtils.isBlank(nseries)) {
					// ignore blank row
					continue;
				}

				if (StringUtils.isBlank(nseries)) {
					Log.warn("标准车系非标准车系修订表中，行 " + (1 + i) + " 非标准车系为空 ");
					continue;
				}

				if (!ssName_ssvoMapping.containsKey(series)) {
					Log.warn("标准车系非标准车系修订表中，行 " + (1 + i) + " 标准车系 " + series
							+ " 有非标准车系，但是没出现在标准车系Ss表中");
					continue;
				}

				String concat = series + "-.-" + nseries;

				if (exists.containsKey(concat)) {
					Log.info("标准车系非标准车系修订表中，行 " + (1 + i) + " 重复的车系修订 " + concat);
					continue;
				}

				SsVO ss = new SsVO(0, series);
				if (ssnsMapping.containsKey(ss)) {
					if (!ssnsMapping.get(ss).contains(nseries)) {
						ssnsMapping.get(ss).add(nseries);
					}
				} else {
					List<String> sbStringList = new ArrayList<String>();
					sbStringList.add(nseries);
					ssnsMapping.put(ss, sbStringList);
				}

				exists.put(concat, series);
			}
		}
		/** 判断ssnsMapping是否都存在于ssList中 */
		Set<SsVO> keys = ssnsMapping.keySet();
		for (SsVO s : keys) {
			if (!ssList.contains(s)) {
				// ssnsMapping.remove(s);
				Log.warn("标准车系中不存在" + s.getSeries() + "");
			}
		}
	}

	private static final void buildSbSsMapping() {
		// 填充sbssMapping
		for (Iterator<SbSsVO> sbssI = sbssList.iterator(); sbssI.hasNext();) {
			SbSsVO ssvo = (SbSsVO) sbssI.next();
			if (sbssMapping.containsKey(ssvo.getsBrandVO())) {
			} else {
				sbssMapping.put(ssvo.getsBrandVO(), new ArrayList<SsVO>());
			}
			sbssMapping.get(ssvo.getsBrandVO()).add(ssvo.getsSeriesVO());
		}

	}

	private static final void buildNbSbMapping() {
		Log.info("按照sbnbMapping，填充nbsbMapping");
		// 按照sbnbMapping，填充nbsbMapping
		if (sbnbMapping != null && sbnbMapping.size() > 0) {
			Set<SbVO> keys = sbnbMapping.keySet();
			for (SbVO key : keys) {
				List<String> values = sbnbMapping.get(key);
				for (String s : values) {
					if (nbsbMapping.containsKey(s)) {
						List<SbVO> slist = nbsbMapping.get(s);
						if (!slist.contains(key)) {
							slist.add(key);
						}
						nbsbMapping.put(s, slist);
					} else {
						List<SbVO> slist = new ArrayList<SbVO>();
						slist.add(key);
						nbsbMapping.put(s, slist);
					}
				}
			}
		}
	}

	private static final void buildNsSsMapping() {
		Log.info("按照ssnsMapping，填充nsssMapping");
		// 按照ssnsMapping，填充nsssMapping
		if (ssnsMapping != null && ssnsMapping.size() > 0) {
			Set<SsVO> keys = ssnsMapping.keySet();
			for (SsVO key : keys) {
				List<String> values = ssnsMapping.get(key);
				for (String s : values) {
					if (nsssMapping.containsKey(s)) {
						List<SsVO> slist = nsssMapping.get(s);
						if (!slist.contains(key)) {
							slist.add(key);
						}
						nsssMapping.put(s, slist);
					} else {
						List<SsVO> slist = new ArrayList<SsVO>();
						slist.add(key);
						nsssMapping.put(s, slist);
					}
				}
			}
		}
	}

	private static final void buildSsSbMapping() {
		Log.info("按照sbssMapping，填充sssbMapping");
		// 按照sbssMapping，填充sssbMapping
		if (sbssMapping != null && sbssMapping.size() > 0) {
			Set<SbVO> keys = sbssMapping.keySet();
			for (SbVO key : keys) {
				List<SsVO> values = sbssMapping.get(key);
				for (SsVO s : values) {
					if (sssbMapping.containsKey(s)) {
						List<SbVO> slist = sssbMapping.get(s);
						if (!slist.contains(key)) {
							slist.add(key);
						}
						sssbMapping.put(s, slist);
					} else {
						List<SbVO> slist = new ArrayList<SbVO>();
						slist.add(key);
						sssbMapping.put(s, slist);
					}
				}
			}
		}
	}

	public final static void init() {
		readAndBuildSbList();
		readAndBuildSsList();

		buildSbName_SbvoMapping();
		buildSsName_SsvoMapping();

		readAndBuildSbSsList();

		readAndBuildSbNbMapping();
		appendSbToSbNbMapping();

		readAndBuildSsNsMapping();
		appendSsToSsNsMapping();

		// readAndBuildSbSsMapping();

		buildSbSsMapping();

		buildNbSbMapping();
		buildNsSsMapping();
		buildSsSbMapping();
		//
		buildNb_SbNbMapping();
		buildNs_SsNsMapping();

		buildSbSsName_SbSsMapping();

		checkAllSbInSbSs();
		checkAllSsInSbSs();

	}

	private static Sheet getWorkBookOfSheet(String name) {
		Workbook wb = null;
		String filepath = basePath + configfile;
		wb = ExcelUtil.getWorkbook(filepath);
		return wb.getSheet(name);
	}

	// public static void main(String agrs[]){
	// SbVO vo=new SbVO();
	// vo.setSbrand("奥迪");
	// List<SbVO> list=new ArrayList<SbVO>();
	// list.add(vo);
	// //SbVO vo2=new SbVO();
	// vo.setSbrand("baoma");
	// if(list.contains(vo)){
	// System.err.println("vo 对象已存在");
	// }else{
	// list.add(vo);
	// }
	// System.out.println(list.size());
	// }

}
